package com.hcc.flow.server.common.utils;

import java.io.File;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.hcc.flow.server.common.dto.GenerateInput;

public class TemplateUtil {

	private static final Logger log = LoggerFactory.getLogger("adminLogger");

	public static String getTemplete(String fileName) {
		return FileUtil.getText(TemplateUtil.class.getClassLoader().getResourceAsStream("generate/" + fileName));
	}

	public static void saveJava(GenerateInput input) {
		String path = input.getPath();
		String beanPackageName = input.getBeanPackageName();
		String beanName = input.getBeanName();
		List<String> beanFieldName = input.getBeanFieldName();
		List<String> beanFieldType = input.getBeanFieldType();
		List<String> beanFieldValue = input.getBeanFieldValue();
		List<String> beanFieldComment = input.getBeanFieldComment();
		String text = getTemplete("java.txt");
		text = text.replace("{beanPackageName}", beanPackageName).replace("{beanName}", beanName);

		String imports = "";
		if (beanFieldType.contains(BigDecimal.class.getSimpleName())) {
			imports += "import " + BigDecimal.class.getName() + ";\n";
		}
		if (beanFieldType.contains(Date.class.getSimpleName())) {
			imports += "import " + Date.class.getName() + ";\n";
			imports += "import " + JsonFormat.class.getName() + ";";
		}

		text = text.replace("{import}", imports);
		String filelds = getFields(beanFieldName, beanFieldType, beanFieldValue,beanFieldComment);
		text = text.replace("{filelds}", filelds);
		text = text.replace("{getset}", getset(beanFieldName, beanFieldType));

		FileUtil.saveTextFile(text, path + File.separator + getPackagePath(beanPackageName) + beanName + ".java");
		log.debug("生成java model：{}模板", beanName);
	}

	private static String getFields(List<String> beanFieldName, List<String> beanFieldType,
			List<String> beanFieldValue,List<String> beanFieldComment) {
		StringBuffer buffer = new StringBuffer();
		int size = beanFieldName.size();
		for (int i = 0; i < size; i++) {
			String name = beanFieldName.get(i);
			/*
			 * if ("id".equals(name) || "createTime".equals(name) ||
			 * "updateTime".equals(name)) { continue; }
			 */
			buffer.append("\t").append("//").append(!name.equals(beanFieldComment.get(i))?beanFieldComment.get(i):"").append("\n");
			String type = beanFieldType.get(i);
			if ("Date".equals(type)) {
				buffer.append("\t").append("@JsonFormat(pattern = \"yyyy-MM-dd HH:mm:ss\",timezone=\"GMT+8\")").append("\n");
			}
			buffer.append("\t").append("private ").append(type).append(" ").append(name);
			// 默认值
			// String value = beanFieldValue.get(i);
			// if (!StringUtilsV2.isEmpty(value)) {
			// buffer.append(" = ");
			// if (type.equals(String.class.getSimpleName())) {
			// value = "\"" + value + "\"";
			// } else if (type.equals(Double.class.getSimpleName())) {
			// value = value + "D";
			// } else if (type.equals(Float.class.getSimpleName())) {
			// value = value + "F";
			// } else if (type.equals(BigDecimal.class.getSimpleName())) {
			// value = "new BigDecimal(" + value + ")";
			// }
			//
			// buffer.append(value);
			// }
			buffer.append(";//\n");
		}

		return buffer.toString();
	}

	private static String getset(List<String> beanFieldName, List<String> beanFieldType) {
		StringBuffer buffer = new StringBuffer();
		int size = beanFieldName.size();
		for (int i = 0; i < size; i++) {
			String name = beanFieldName.get(i);
			/*
			 * if ("id".equals(name) || "createTime".equals(name) ||
			 * "updateTime".equals(name)) { continue; }
			 */

			String type = beanFieldType.get(i);
			buffer.append("\tpublic ").append(type).append(" get")
					.append(StringUtilsV2.substring(name, 0, 1).toUpperCase() + name.substring(1, name.length()))
					.append("() {\n");
			buffer.append("\t\treturn ").append(name).append(";\n");
			buffer.append("\t}\n");
			buffer.append("\tpublic void set")
					.append(StringUtilsV2.substring(name, 0, 1).toUpperCase() + name.substring(1, name.length()))
					.append("(").append(type).append(" ").append(name).append(") {\n");
			buffer.append("\t\tthis.").append(name).append(" = ").append(name).append(";\n");
			buffer.append("\t}\n");
		}

		return buffer.toString();
	}

	public static void saveJavaDao(GenerateInput input) {
		String path = input.getPath();
		String tableName = input.getTableName();
		String beanPackageName = input.getBeanPackageName();
		String beanName = input.getBeanName();
		String daoPackageName = input.getDaoPackageName();
		String daoName = input.getDaoName();
		String beanId = input.getBeanId();

		String text = getTemplete("dao.txt");
		text = text.replace("{daoPackageName}", daoPackageName);
		text = text.replace("{beanPackageName}", beanPackageName);
		text = text.replace("{daoName}", daoName);
		text = text.replace("{table_name}", tableName);
		text = text.replace("{beanName}", beanName);
		text = text.replace("{beanParamName}", lowerFirstChar(beanName));
		text = text.replace("{bean_id}", beanId);
		text = text.replace("{beanId}", StrUtil.str2hump(beanId));

		String insertColumns = getInsertColumns(input.getColumnNames());
		text = text.replace("{insert_columns}", insertColumns);
		String insertValues = getInsertValues(input.getColumnNames(), input.getBeanFieldName());
		text = text.replace("{insert_values}", insertValues);
		FileUtil.saveTextFile(text, path + File.separator + getPackagePath(daoPackageName) + daoName + ".java");
		log.debug("生成java dao：{}模板", beanName);

		text = getTemplete("mapper.xml");
		text = text.replace("{daoPackageName}", daoPackageName);
		text = text.replace("{daoName}", daoName);
		text = text.replace("{table_name}", tableName);
		text = text.replace("{beanName}", beanName);
		text = text.replace("{bean_id}", beanId);
		text = text.replace("{beanId}", StrUtil.str2hump(beanId));
		String sets = getUpdateSets(input.getColumnNames(), input.getBeanFieldName(), tableName);
		text = text.replace("{update_sets}", sets);
		String where = getWhere(input.getColumnNames(), input.getBeanFieldName());
		text = text.replace("{where}", where);
		FileUtil.saveTextFile(text, path + File.separator + beanName + "Mapper.xml");
	}

	private static String getInsertValues(List<String> columnNames, List<String> beanFieldName) {
		StringBuffer buffer = new StringBuffer();
		int size = columnNames.size();
		for (int i = 0; i < size; i++) {
			String column = columnNames.get(i);
			if (!"id".equals(column)) {
				if ("create_time".equals(column)) 
					buffer.append("now(), ");
				else
					buffer.append("#{").append(beanFieldName.get(i)).append("}, ");
			}
		}

		String sets = StringUtilsV2.substringBeforeLast(buffer.toString(), ",");
		return sets;
	}

	private static String getInsertColumns(List<String> columnNames) {
		StringBuffer buffer = new StringBuffer();
		int size = columnNames.size();
		for (int i = 0; i < size; i++) {
			String column = columnNames.get(i);
			if (!"id".equals(column)) {
				buffer.append(column).append(", ");
			}
		}

		String insertColumns = StringUtilsV2.substringBeforeLast(buffer.toString(), ",");
		return insertColumns;
	}

	private static String getUpdateSets(List<String> columnNames, List<String> beanFieldName, String tableName) {
		StringBuffer buffer = new StringBuffer();
		StringBuffer id_str = new StringBuffer().append(tableName).append("_id");
		int size = columnNames.size();
		for (int i = 0; i < size; i++) {
			String column = columnNames.get(i);
			String beanName = beanFieldName.get(i);
			if (!id_str.toString().equals(column) && !"create_user_id".equals(column)
					&& !"create_time".equals(column)) {
				buffer.append("\t\t\t<if test=\"" + beanName + " != null\">\n");
				buffer.append("\t\t\t\t" + column).append(" = ").append("#{").append(beanName).append("}, \n");
				buffer.append("\t\t\t</if>\n");
			}
		}

		return buffer.toString();
	}

	private static String getWhere(List<String> columnNames, List<String> beanFieldName) {
		StringBuffer buffer = new StringBuffer();
		int size = columnNames.size();
		for (int i = 0; i < size; i++) {
			String column = columnNames.get(i);
			String beanName = beanFieldName.get(i);
			buffer.append("\t\t\t<if test=\"params." + beanName + " != null and params." + beanName + " != ''\">\n");
			buffer.append("\t\t\t\tand " + column).append(" = ").append("#{params.").append(beanName).append("} \n");
			buffer.append("\t\t\t</if>\n");
		}

		return buffer.toString();
	}

	/**
	 * 变量名
	 * 
	 * @param beanName
	 * @return
	 */
	public static String lowerFirstChar(String beanName) {
		String name = StrUtil.str2hump(beanName);
		String firstChar = name.substring(0, 1);
		name = name.replaceFirst(firstChar, firstChar.toLowerCase());

		return name;
	}

	private static String getPackagePath(String packageName) {
		String packagePath = packageName.replace(".", "/");
		if (!packagePath.endsWith("/")) {
			packagePath = packagePath + "/";
		}

		return packagePath;
	}

	public static void saveController(GenerateInput input) {
		String path = input.getPath();
		String beanPackageName = input.getBeanPackageName();
		String beanName = input.getBeanName();
		String daoPackageName = input.getDaoPackageName();
		String daoName = input.getDaoName();

		String text = getTemplete("controller.txt");
		text = text.replace("{daoPackageName}", daoPackageName);
		text = text.replace("{beanPackageName}", beanPackageName);
		text = text.replace("{daoName}", daoName);
		text = text.replace("{daoParamName}", lowerFirstChar(daoName));
		text = text.replace("{beanName}", beanName);
		text = text.replace("{beanParamName}", lowerFirstChar(beanName));
		text = text.replace("{controllerPkgName}", input.getControllerPkgName());
		text = text.replace("{controllerName}", input.getControllerName());

		FileUtil.saveTextFile(text, path + File.separator + getPackagePath(input.getControllerPkgName())
				+ input.getControllerName() + ".java");
		log.debug("生成controller：{}模板", beanName);
	}

	public static void saveHtmlList(GenerateInput input) {
		String path = input.getPath();
		String beanName = input.getBeanName();
		String beanParamName = lowerFirstChar(beanName);
		String beanId = input.getBeanId();
		String text = getTemplete("htmlList.txt");
		text = text.replace("{beanParamName}", beanParamName);
		text = text.replace("{beanId}", StrUtil.str2hump(beanId));
		text = text.replace("{beanName}", beanName);
		List<String> beanFieldNames = input.getBeanFieldName();
		List<String> beanFieldComments = input.getBeanFieldComment();
		text = text.replace("{columnsDatas}", getHtmlColumnsDatas(beanFieldNames));
		text = text.replace("{ths}", getHtmlThs(beanFieldComments));

		FileUtil.saveTextFile(text, path + File.separator + beanParamName + "List.html");
		log.debug("生成查询页面：{}模板", beanName);

		text = getTemplete("htmlAdd.txt");
		text = text.replace("{beanParamName}", beanParamName);
		text = text.replace("{addDivs}", getAddDivs(beanFieldNames,StrUtil.str2hump(beanId),beanFieldComments));
		FileUtil.saveTextFile(text, path + File.separator + "add" + beanName + ".html");
		log.debug("生成添加页面：{}模板", beanName);

		text = getTemplete("htmlUpdate.txt");
		text = text.replace("{beanId}", StrUtil.str2hump(beanId));
		text = text.replace("{beanParamName}", beanParamName);
		text = text.replace("{addDivs}", getAddDivs(beanFieldNames,StrUtil.str2hump(beanId),beanFieldComments));
		text = text.replace("{initData}", getInitData(beanFieldNames));
		FileUtil.saveTextFile(text, path + File.separator + "update" + beanName + ".html");
		log.debug("生成修改页面：{}模板", beanName);
	}

	private static CharSequence getInitData(List<String> beanFieldNames) {
		StringBuilder builder = new StringBuilder();
		beanFieldNames.forEach(b -> {
			builder.append("\t\t\t\t\t\t$('#" + b + "').val(data." + b + ");\n");
		});

		return builder.toString();
	}

	private static String getAddDivs(List<String> beanFieldNames,String beanId,List<String> beanFieldComments) {
		StringBuilder builder = new StringBuilder();
		int size = beanFieldNames.size();
		for (int i = 0; i < size; i++) {
			String name = beanFieldNames.get(i);
			if (!beanId.equals(beanFieldNames.get(i)) 
					&& !"status".equals(name) 
					&& !"indexId".equals(name) 
					&& !"createTime".equals(name) 
					&& !"createUserId".equals(name) 
					&& !"updateTime".equals(name)
					&& !"submitterId".equals(name)
					&& !"verifyUserId".equals(name)
					&& !"verifyTime".equals(name)
					&& !"createOrgId".equals(name)
					&& !"followOrgId".equals(name)) {
				builder.append("\t\t\t<div class='form-group'>\n");
				builder.append("\t\t\t\t<label class='col-md-2 control-label'>" + beanFieldComments.get(i) + "</label>\n");
				builder.append("\t\t\t\t<div class='col-md-10'>\n");
				builder.append("\t\t\t\t\t<input class='form-control' type='text' "
						+ "name='" + name + "' id='" + name + "' data-bv-notempty='true' data-bv-notempty-message='" + beanFieldComments.get(i) + " 不能为空'>\n");
				builder.append("\t\t\t\t</div>\n");
				builder.append("\t\t\t</div>\n");
			}
		}
		/*beanFieldNames.forEach(b -> {
			if (!beanId.equals(b) && !"createTime".equals(b) && !"updateTime".equals(b)) {
				builder.append("\t\t\t<div class='form-group'>\n");
				builder.append("\t\t\t\t<label class='col-md-2 control-label'>" + b + "</label>\n");
				builder.append("\t\t\t\t<div class='col-md-10'>\n");
				builder.append("\t\t\t\t\t<input class='form-control' type='text' "
						+ "name='" + b + "' id='" + b + "' data-bv-notempty='true' data-bv-notempty-message='" + b + " 不能为空'>\n");
				builder.append("\t\t\t\t</div>\n");
				builder.append("\t\t\t</div>\n");
			}
		});*/
		return builder.toString();
	}

	private static String getHtmlThs(List<String> beanFieldComments) {
		StringBuilder builder = new StringBuilder();
		beanFieldComments.forEach(b -> {
			builder.append("\t\t\t\t\t\t\t\t\t<th>{beanFieldName}</th>\n".replace("{beanFieldName}", b));
		});
		return builder.toString();
	}

	private static String getHtmlColumnsDatas(List<String> beanFieldNames) {
		StringBuilder builder = new StringBuilder();
		beanFieldNames.forEach(b -> {
			String bb = b;
			if("status".equals(bb)){
				bb = "statusName";
			}else if("createUserId".equals(bb)){
				bb = "createUserName";
			}
			builder.append("\t\t\t\t{\"data\" : \"{beanFieldName}\", \"defaultContent\" : \"\"},\n"
					.replace("{beanFieldName}", bb));
		});

		builder.append("");
		return builder.toString();
	}

}
